﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using StructureMap;
using Moq;
using System.Windows.Forms;
using AutomationView.Views;

namespace AutomationView.Test
{
    [TestClass]
    public class CustomerMgntTest
    {
        CustomersEngine engine;
        string message;
        [TestInitialize]
        public void StartUp()
        {
            #region Mock form

            var mock = new Moq.Mock<Helper.FormRenderer>();

            mock.Setup(v => v.Show(It.IsAny<Control>())).Callback((Control c) =>
            {
                message = c.GetType().Name + " Shown";
            });

            mock.Setup(v => v.Show(It.IsAny<string>())).Callback((string s) =>
            {
                message = "MessageBox Show";
            });

            ObjectFactory.Inject<Helper.FormRenderer>(mock.Object);
            #endregion

            engine = SimpleFactory.GetObject<CustomersEngine>();
            engine.Start();
        }

        [TestMethod]
        public void AddTwoCustomers()
        {
            var count = engine.Customers.Count;

            //Add a customer
            engine.Accept(FormCustomersEngine.Operations.Add);
            Input("Name", "西方来拜");
            Input("CompanyName", "西方");
            Input("DateOfBirth", DateTime.Now.AddYears(-5));
            engine.Accept(AddCustomerEngine.Operations.Save);

            //Test cancel add
            engine.Accept(FormCustomersEngine.Operations.Add);           
            Assert.AreEqual(ViewState.Customers.Adding, engine.CurrentState);
            engine.Accept(AddCustomerEngine.Operations.Cancel);

            //Test add again
            engine.Accept(FormCustomersEngine.Operations.Add);
            Input("Name", "东方来拜");
            Input("CompanyName", "东方");
            Input("DateOfBirth", DateTime.Now.AddYears(-55));
            engine.Accept(AddCustomerEngine.Operations.Save);

            Assert.AreEqual("AddCustomerEngineView Shown", message);
            Assert.AreEqual(engine.Customers.Count, count + 2);
        }

        [TestMethod]
        public void AddInvalid()
        {
            engine.Accept(FormCustomersEngine.Operations.Add);

            ViewState state = null;

            engine.StateChanged += s =>
            {
                if(state == null) state = s;
            };
            engine.Accept(AddCustomerEngine.Operations.Save);

            Assert.AreEqual("MessageBox Show", message);
            Assert.AreEqual(ViewState.AddCustomer.Error, state);
        }

        #region Inner methods

        void Input(params object[] args)
        {
            engine.Accept(AddCustomerEngine.Operations.Input.UseArguments(args));
        }

        #endregion
    }
}
